package com.share.trigger.http;

import com.alibaba.fastjson.JSON;
import com.share.domain.activity.service.IRaffleActivityAccountQuotaService;
import com.share.domain.strategy.model.entity.RaffleAwardEntity;
import com.share.domain.strategy.model.entity.RaffleFactorEntity;
import com.share.domain.strategy.model.entity.StrategyAwardEntity;
import com.share.domain.strategy.model.vo.RuleWeightVo;
import com.share.domain.strategy.service.IRaffleAward;
import com.share.domain.strategy.service.IRaffleRule;
import com.share.domain.strategy.service.IRaffleStrategy;
import com.share.domain.strategy.service.armory.IStrategyArmory;
import com.share.trigger.api.IRaffleStrategyService;
import com.share.trigger.api.dto.Raffle.*;
import com.share.types.enums.ResponseCode;
import com.share.types.exception.AppException;
import com.share.types.model.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 抽奖服务
 */
@Slf4j
@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/api/${app.config.api-version}/raffle/strategy")
public class RaffleStrategyController implements IRaffleStrategyService {

    @Resource
    private IStrategyArmory strategyArmory;

    @Resource
    private IRaffleRule raffleRule;
    @Resource
    private IRaffleAward raffleAward;

    @Resource
    private IRaffleStrategy raffleStrategy;

    @Resource
    private IRaffleActivityAccountQuotaService quotaService;

//http://localhost:8091/api/v1/raffle/strategy_armory?strategy=100006
    @RequestMapping(value = "strategy_armory",method = RequestMethod.GET)
    @Override
    public Response<Boolean> strategyArmory(@RequestParam("strategyId") Long strategyId) {
        try {
            log.info("策略：{}:抽奖策略装配【开始】",strategyId);

            boolean armoryStatus = strategyArmory.assembleLotteryStrategy(strategyId);
            Response<Boolean> res = Response.<Boolean>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(armoryStatus)
                    .build();
            log.info("策略：{}:抽奖策略装配【成功】",strategyId);
            return res;
        }catch (Exception e){
            log.error("策略：{}:抽奖策略装配【失败】",strategyId);
            return Response.<Boolean> builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .build();
        }
    }

    @RequestMapping(value = "query_raffle_award_list",method = RequestMethod.POST)
    @Override
    public Response<List<RaffleAwardListResponseDTO>> queryRaffleAwardList(@RequestBody RaffleAwardListRequestDTO requestDTO) {
        try {
            log.info("【开始】【查询抽奖列表】:::userId:{},activityId:{}",requestDTO.getUserId(),requestDTO.getActivityId());
            //1.参数校验
            if(StringUtils.isBlank(requestDTO.getUserId())||null==requestDTO.getActivityId()){
                return Response.<List<RaffleAwardListResponseDTO>> builder()
                        .code(ResponseCode.ILLEGAL_PARAMETER.getCode())
                        .info(ResponseCode.ILLEGAL_PARAMETER.getInfo())
                        .build();
            }
            //查询奖品配置
            List<StrategyAwardEntity> strategyAwardEntities = raffleAward.queryRaffleStrategyAwardListByActivityId(requestDTO.getActivityId());

            //3。获取规则配置
            String[] treeIds = strategyAwardEntities.stream()
                    .map(StrategyAwardEntity::getRuleModels)
                    .filter(ruleModel->ruleModel!=null&&!ruleModel.isEmpty())
                    .toArray(String[]::new);
            //4.查询规则配置-获取奖品的解锁限制
            Map<String, Integer> ruleLockCountMap = raffleRule.queryAwardRuleLockCount(treeIds);
            //5.查询用户已经抽奖次数
            Integer dayPartakeCount = quotaService.queryRaffleActivityAccountDayPartakeCount(requestDTO.getActivityId(),requestDTO.getUserId());
            //6.遍历填充数据
            ArrayList<RaffleAwardListResponseDTO> raffleAwardListResponseDTOs = new ArrayList<>(strategyAwardEntities.size());

            for(StrategyAwardEntity entity:strategyAwardEntities){
                Integer AwardLockCount = ruleLockCountMap.get(entity.getRuleModels());
                raffleAwardListResponseDTOs.add(RaffleAwardListResponseDTO.builder()
                        .awardId(entity.getAwardId())
                        .awardTitle(entity.getAwardTitle())
                        .awardSubTitle(entity.getAwardSubTitle())
                        .sort(entity.getSort())
                        .awardRuleLockCount(AwardLockCount)
                        .isAwardLock(null== AwardLockCount ||dayPartakeCount<AwardLockCount)
                        .awaitUnlockCount(null==AwardLockCount||AwardLockCount<=dayPartakeCount ?0:AwardLockCount-dayPartakeCount)
                        .build());

            }
            Response<List<RaffleAwardListResponseDTO>> res = Response.<List<RaffleAwardListResponseDTO>>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(raffleAwardListResponseDTOs)
                    .build();
            log.info("【成功】【查询抽奖列表】:::userId:{},activityId:{}，response:{}",requestDTO.getUserId(),requestDTO.getActivityId(),JSON.toJSONString(res));
            return res;
        }catch (Exception e){
            log.info("【失败】【查询抽奖列表】:::userId:{},activityId:{}",requestDTO.getUserId(),requestDTO.getActivityId());
            return Response.<List<RaffleAwardListResponseDTO>> builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .build();
        }
    }



    @RequestMapping(value = "random_raffle",method = RequestMethod.POST)
    @Override
    public Response<RaffleStrategyResponseDTO> randomRaffle(@RequestBody RaffleStrategyRequestDTO RaffleStrategyRequestDTO) {
        try {
            log.info("策略:{}-抽奖【开始】",RaffleStrategyRequestDTO.getStrategyId());
            //调用抽奖接口
            RaffleFactorEntity raffleFactorEntity = RaffleFactorEntity.builder()
                    .strategyId(RaffleStrategyRequestDTO.getStrategyId())
                    .userId(RaffleStrategyRequestDTO.getUserId())
                    .build();
            RaffleAwardEntity raffleAwardEntity = raffleStrategy.performRaffle(raffleFactorEntity);

            Response<RaffleStrategyResponseDTO> res = Response.<RaffleStrategyResponseDTO>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(RaffleStrategyResponseDTO.builder()
                            .awardId(raffleAwardEntity.getAwardId())
                            .awardIndex(raffleAwardEntity.getSort())
                            .build())
                    .build();

            log.info("策略:{}-抽奖【成功】-抽奖结果:{}",RaffleStrategyRequestDTO.getStrategyId(), JSON.toJSONString(res));
            return res;
        }catch (AppException e) {
            log.error("策略:{}-抽奖【失败】-失败原因:{}",RaffleStrategyRequestDTO.getStrategyId(),e.getInfo());
            return Response.<RaffleStrategyResponseDTO> builder()
                    .code(e.getCode())
                    .info(e.getInfo())
                    .build();


        }catch (Exception e){
            log.error("策略:{}-抽奖【失败】",RaffleStrategyRequestDTO.getStrategyId());
            return Response.<RaffleStrategyResponseDTO> builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .build();
        }
    }

    @Override
    public Response<List<RaffleStrategyRuleWeightResponseDTO>> queryRaffleStrategyRuleWeight(RaffleStrategyRuleWeightRequestDTO request) {
        try {
            log.info("[开始]查询抽奖策略权重配置,userId:{},activityId:{}", request.getUserId(), request.getActivityId());
            //1.参数校验
            if (StringUtils.isBlank(request.getUserId()) || null == request.getActivityId()) {
                return Response.<List<RaffleStrategyRuleWeightResponseDTO>>builder()
                        .code(ResponseCode.ILLEGAL_PARAMETER.getCode())
                        .info(ResponseCode.ILLEGAL_PARAMETER.getInfo())
                        .build();
            }

            //2.查询用户抽奖总次数
            Integer totalCount = quotaService.queryRaffleActivityAccountTotalPartakeCount(request.getActivityId(), request.getUserId());
            //3.查询
            List<RuleWeightVo> ruleWeightVoList = raffleRule.queryRuleWeightByActivityId(request.getActivityId());
            List<RaffleStrategyRuleWeightResponseDTO> response = new ArrayList<>(ruleWeightVoList.size());
            for (RuleWeightVo ruleWeightVo : ruleWeightVoList) {
                List<RaffleStrategyRuleWeightResponseDTO.strategyAward> strategyAwards = new ArrayList<>(ruleWeightVo.getAwardIds().size());
                for (RuleWeightVo.Award award : ruleWeightVo.getAwardList()) {
                    RaffleStrategyRuleWeightResponseDTO.strategyAward strategyAward = new RaffleStrategyRuleWeightResponseDTO.strategyAward();
                    strategyAward.setAwardId(award.getAwardId());
                    strategyAward.setAwardTitle(award.getAwardTitle());
                    strategyAwards.add(strategyAward);
                }
                response.add(RaffleStrategyRuleWeightResponseDTO.builder()
                        .strategyAwards(strategyAwards)
                        .ruleWeightCount(ruleWeightVo.getWeight())
                        .userRuleWeightCount(totalCount)
                        .build());
            }
            log.info("[成功]查询抽奖策略权重配置,userId:{},activityId:{},结果：{}", request.getUserId(), request.getActivityId(), JSON.toJSONString(response));

            return Response.<List<RaffleStrategyRuleWeightResponseDTO>>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .info(ResponseCode.SUCCESS.getInfo())
                    .data(response)
                    .build();


        } catch (Exception e) {
            log.info("[失败]查询抽奖策略权重配置,userId:{},activityId:{}", request.getUserId(), request.getActivityId());
            return Response.<List<RaffleStrategyRuleWeightResponseDTO>>builder()
                    .code(ResponseCode.UN_ERROR.getCode())
                    .info(ResponseCode.UN_ERROR.getInfo())
                    .build();
        }
    }
}
